package com.bms.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.springframework.stereotype.Service;

import com.bms.dao.IPRangeDao;
import com.bms.entity.IPRange;
import com.bms.service.IPRangeService;
import com.bms.utils.Constant;
import com.bms.utils.IPUtil;

@Service
public class IPRangeServiceImpl extends BaseServiceImpl<IPRange, String> implements IPRangeService {

	@Resource
	private IPRangeDao ipRangeDao;

	@Resource
	public void setBaseDao(IPRangeDao ipRangeDao) {
		super.setBaseDao(ipRangeDao);
	}

	/**
	 * @return the ipRangeDao
	 */
	public IPRangeDao getIPRangeDao() {
		return ipRangeDao;
	}

	/**
	 * @param ipRangeDao the ipRangeDao to set
	 */
	public void setIPRangeDao(IPRangeDao ipRangeDao) {
		this.ipRangeDao = ipRangeDao;
	}

	public List<IPRange> getAreas() {
		DetachedCriteria criteria = DetachedCriteria.forClass(IPRange.class);
		
		ProjectionList proList = Projections.projectionList();
		proList.add(Projections.min("id").as("id"));
	    proList.add(Projections.groupProperty("areaName").as("areaName"));
	    
	    criteria.setProjection(proList);
	    criteria.setResultTransformer(new AliasToBeanResultTransformer(IPRange.class));
	    return ipRangeDao.getList(criteria);
	}
	
	public IPRange inRange(String clientIP){
		List<IPRange> ipRanges = ipRangeDao.getAll();
		
		long ip = IPUtil.parseIP(clientIP);
		IPRange ipRange = null;
		
		for(IPRange entity : ipRanges){
			long start = IPUtil.parseIP(entity.getStartIP());
			long mask = 0;
			
			if(StringUtils.isNotBlank(entity.getMask())){
				if(entity.getMask().matches(Constant.REGX_IP)){
					mask = IPUtil.parseIP(entity.getMask());
				}else if(StringUtils.isNumeric(entity.getMask())){
					mask = IPUtil.parseMask(Integer.parseInt(entity.getMask()));
				}
			}
			
			if(IPUtil.isInRange(ip, start, mask)){
				ipRange = entity;
				break;
			}
		}
		
		return ipRange;
	}

}